<template>
  <el-main >
    <el-button
        type="primary"
        :icon="Plus"
        size="default"
        @click="addBtn">新增
    </el-button>
    <el-table

        style="margin-top: 20px;"
        :data="tableList"
        row-key="menuId"
        stripe
        :height="tableHeight"
        default-expand-all
        border>
      <el-table-column
          label="菜单名称"
          prop="title"></el-table-column>
      <el-table-column
          label="菜单图标"
          prop="icon">
        <template #default="scope">
          <el-icon v-if="scope.row.icon">
            <component :is="scope.row.icon"></component>
          </el-icon>
        </template>
      </el-table-column>
      <el-table-column
          label="菜单类型"
          prop="type">
        <template #default="scope">
          <el-tag
              v-if="scope.row.type=='0'"
              type="primary"
              size="default">目录
          </el-tag>
          <el-tag
              v-if="scope.row.type=='1'"
              type="warning"
              size="default">菜单
          </el-tag>
          <el-tag
              v-if="scope.row.type=='2'"
              type="danger"
              size="default">按钮
          </el-tag>
        </template>
      </el-table-column>
      <el-table-column
          label="上级菜单"
          prop="parentName"></el-table-column>
      <el-table-column
          label="路由名称"
          prop="name"></el-table-column>
      <el-table-column
          label="路由地址"
          prop="path"></el-table-column>
      <el-table-column
          label="组件路径"
          prop="url"></el-table-column>
      <el-table-column
          label="权限字段"
          prop="code"></el-table-column>
      <el-table-column
          label="序号"
          prop="orderNum"></el-table-column>
      <el-table-column
          label="操作"
          align="center">
        <template #default="scope">
          <el-button
              type="primary"
              @click="editBtn(scope.row)"
              icon="Edit">编辑
          </el-button>
          <el-button
              type="danger"
              @click="deleteBtn(scope.row.menuId)"
              icon="Delete">删除
          </el-button>
        </template>
      </el-table-column>
    </el-table>
    <SysDialog
        :height="dialog.height"
        :visible="dialog.visible"
        :width="dialog.width"
        :title="dialog.title"
        @onCLose="onClose"
        @on-confirm="commit">
      <template v-slot:content>
        <el-form
            :model="addModel"
            ref="addForm"
            :rules="rules"
            label-width="80px"
            :inline="false"
            size="default">
          <el-form-item
              label="菜单类型"
              prop="type">
            <el-radio-group v-model="addModel.type">
              <el-radio :label="'0'">目录</el-radio>
              <el-radio :label="'1'">菜单</el-radio>
              <el-radio :label="'2'">按钮</el-radio>
            </el-radio-group>
          </el-form-item>
          <el-row :gutter="20">
            <el-col :span="12">
              <el-form-item
                  label="上级菜单"
                  prop="parentId">
                <el-tree-select
                    @check-change="treeClick"
                    v-model="addModel.parentId"
                    :data="parentTree"
                    :render-after-expand="false"
                    check-strictly
                    show-checkbox />
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item
                  label="菜单名称"
                  prop="title">
                <el-input v-model="addModel.title"></el-input>
              </el-form-item>
            </el-col>
          </el-row>
          <el-row
              v-if="addModel.type!='2'"
              :gutter="20">
            <el-col :span="12">
              <el-form-item
                  label="菜单图标"
                  prop="icon">
                <el-popover
                    placement="bottom-start"
                    :width="400"
                    trigger="click">
                  <template #reference>
                    <el-input
                        v-model="addModel.icon"
                        placeholder="点击选择图标"
                        readonly>
                      <template #prefix>
                        <el-icon v-if="addModel.icon">
                          <component :is="addModel.icon"></component>
                        </el-icon>
                      </template>
                    </el-input>
                  </template>
                  <div class="icon-selector">
                    <div class="icon-search">
                      <el-input
                          v-model="iconSearch"
                          placeholder="搜索图标"
                          clearable
                          prefix-icon="Search" />
                    </div>
                    <div class="icon-list">
                      <div
                          v-for="icon in filteredIcons"
                          :key="icon"
                          class="icon-item"
                          :class="{ 'icon-active': addModel.icon === icon }"
                          @click="selectIcon(icon)">
                        <el-icon>
                          <component :is="icon" />
                        </el-icon>
                        <span class="icon-name">{{ icon }}</span>
                      </div>
                    </div>
                  </div>
                </el-popover>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item
                  label="路由名称"
                  prop="name">
                <el-input v-model="addModel.name"></el-input>
              </el-form-item>
            </el-col>
          </el-row>
          <el-row :gutter="20">
            <el-col :span="12">
              <el-form-item
                  label="菜单序号"
                  prop="orderNum">
                <el-input v-model="addModel.orderNum"></el-input>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item
                  label="权限字段"
                  prop="code">
                <el-input v-model="addModel.code"></el-input>
              </el-form-item>
            </el-col>
          </el-row>
          <el-row :gutter="20">
            <el-col
                :span="12"
                v-if="addModel.type!=='2'">
              <el-form-item
                  label="路由地址"
                  prop="path">
                <el-input v-model="addModel.path"></el-input>
              </el-form-item>
            </el-col>
            <el-col
                :span="12"
                v-if="addModel.type =='1'">
              <el-form-item
                  label="组件路径"
                  prop="url">
                <el-input v-model="addModel.url"></el-input>
              </el-form-item>
            </el-col>
          </el-row>
        </el-form>
      </template>
    </SysDialog>
  </el-main>
</template>

<script
    setup
    lang="ts">
  import useDialog from '@/hocks/useDialog.ts'
  import SysDialog from "@/components/SysDialog.vue";
  import {nextTick, onMounted, reactive, ref, computed} from "vue";
  import type {FormInstance} from 'element-plus'
  import {ElMessage} from 'element-plus'
  import {Plus} from "@element-plus/icons-vue";
  import {addApi, deleteApi, editApi, getListApi, getParentApi} from "@/api/menu";
  import type {MenuType} from "@/api/menu/MenuModel.ts";
  import useInstance from "@/hocks/useInstance.ts";
  import {eventBus} from "@/utils/eventBus.ts";

  //弹框属性
  const {dialog, onShow, onClose} = useDialog()

  //获取上级菜单树
  const parentTree = ref([])
  const getParent = async () => {
    let res = await getParentApi()
    if (res && res.code == 200) {
      parentTree.value = res.data
    }
  }

  const tags = ref('')
  //新增按钮
  const addBtn = async () => {
    tags.value = '0'
    addModel.menuId = ''
    dialog.title = "新增菜单"
    await getParent()
    onShow()
    addForm.value?.resetFields()//清空表单，放onShow后面
    // 🟢 新增：触发菜单更新事件
  }

  const editBtn = async (menu: MenuType) => {
    tags.value = '1'
    dialog.title = '编辑菜单'
    onShow()
    await getParent()
    //回显数据
    nextTick(() => {
      Object.assign(addModel, menu)
    })
    addForm.value?.resetFields()
  }

  const {global} = useInstance()
  const deleteBtn = async (menuId: string) => {
    const confirm = await global.$myConfirm('确定删除吗？')
    if (confirm) {
      let res = await deleteApi(menuId)
      if (res && res.code == 200) {
        ElMessage.success(res.msg)
        await getList()
        onClose()
        eventBus.emit('menu-updated')
      }
    }
  }
  const addForm = ref<FormInstance>()
  const rules = reactive({
    parentId: [{
      required: true,
      message: '请选择上级菜单',
      trigger: ['change', 'blur']
    }],
    name: [{
      required: true,
      message: '请填写路由名称',
      trigger: ['change', 'blur']
    }],
    orderNum: [{
      required: true,
      message: '请填写排序号',
      trigger: ['change', 'blur']
    }],
    title: [{
      required: true,
      message: '请填写菜单名称',
      trigger: ['change', 'blur']
    }],
    icon: [{
      required: true,
      message: '请选择菜单图标',
      trigger: ['change', 'blur']
    }],
    url: [{
      required: true,
      message: '请填写组件路径',
      trigger: ['change', 'blur']
    }],
    path: [{
      required: true,
      message: '请填写路由地址',
      trigger: ['change', 'blur']
    }],
    type: [{
      required: true,
      message: '请选择菜单类型',
      trigger: ['change', 'blur']
    }],
    code: [{
      required: true,
      message: '请填写权限字段',
      trigger: ['change', 'blur']
    }],
  })
  //新增表单绑定对象
  const addModel = reactive({
    menuId: '',
    parentId: '',
    title: '',
    code: '',
    name: '',
    path: '',
    url: '',
    type: '',
    icon: '',
    parentName: '',
    orderNum: '',
  })

  // 图标选择器
  const iconList = [
    'HomeFilled', 'User', 'Setting', 'Menu', 'Folder', 'Document', 'DataBoard', 'Monitor',
    'Grid', 'List', 'Collection', 'ChatDotRound', 'Promotion', 'TrendCharts', 'Box',
    'ShoppingCart', 'Goods', 'Present', 'Coin', 'CreditCard', 'Wallet', 'Flag', 'Star',
    'Location', 'MapLocation', 'Message', 'ChatLineRound', 'Phone', 'VideoCamera',
    'Camera', 'Microphone', 'Headset', 'Bell', 'Notification', 'Connection', 'Link',
    'Position', 'Rank', 'Histogram', 'DataLine', 'PieChart', 'Odometer', 'Stopwatch',
    'Timer', 'AlarmClock', 'Watch', 'Lock', 'Unlock', 'Key', 'Tools', 'Management',
    'Aim', 'View', 'Hide', 'Search', 'ZoomIn', 'ZoomOut', 'Refresh', 'RefreshRight',
    'RefreshLeft', 'Download', 'Upload', 'Top', 'Bottom', 'Left', 'Right', 'Sort',
    'SortUp', 'SortDown', 'Rank', 'CaretLeft', 'CaretRight', 'CaretTop', 'CaretBottom',
    'DArrowLeft', 'DArrowRight', 'ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown',
    'Back', 'Right', 'Top', 'Bottom', 'TopRight', 'TopLeft', 'BottomRight', 'BottomLeft',
    'Check', 'Close', 'Plus', 'Minus', 'CirclePlus', 'CircleMinus', 'CircleCheck',
    'CircleClose', 'SuccessFilled', 'WarningFilled', 'InfoFilled', 'RemoveFilled',
    'CircleCloseFilled', 'Check', 'Close', 'Loading', 'Warning', 'QuestionFilled',
    'Info', 'Remove', 'CircleCheck', 'CircleClose', 'Success', 'Warning', 'Info',
    'Delete', 'DeleteFilled', 'Remove', 'Edit', 'EditPen', 'More', 'MoreFilled',
    'Star', 'StarFilled', 'Message', 'MessageBox', 'ChatDotSquare', 'ChatDotRound',
    'ChatLineSquare', 'ChatLineRound', 'ChatSquare', 'ChatRound', 'Postcard', 'Position',
    'TurnOff', 'Open', 'FolderOpened', 'FolderDelete', 'FolderChecked', 'FolderRemove',
    'FolderAdd', 'CollectionTag', 'Operation', 'Cpu', 'Memo', 'Calendar', 'AlarmClock',
    'Medal', 'Trophy', 'TrophyBase', 'FirstAidKit', 'Reading', 'DataAnalysis', 'Printer',
    'CopyDocument', 'Files', 'Notebook', 'DocumentCopy', 'DocumentChecked', 'DocumentAdd',
    'DocumentRemove', 'DocumentDelete', 'Document', 'DataBoard', 'House', 'School',
    'OfficeBuilding', 'Shop', 'MilkTea', 'CoffeeCup', 'ColdDrink', 'Dish', 'Bowl',
    'KnifeFork', 'Chicken', 'Food', 'Orange', 'Pear', 'Apple', 'Cherry', 'Watermelon',
    'Grape', 'Basketball', 'Football', 'Soccer', 'Baseball'
  ]

  const iconSearch = ref('')
  const filteredIcons = computed(() => {
    if (!iconSearch.value) return iconList
    return iconList.filter(icon =>
        icon.toLowerCase().includes(iconSearch.value.toLowerCase())
    )
  })

  const selectIcon = (icon: string) => {
    addModel.icon = icon
  }

  //上级菜单树选中事件
  const treeClick = (item: any) => {
    addModel.parentName = item.title
  }
  const commit = () => {
    addForm.value?.validate(async (valid) => {
      if (valid) {
        let res: any
        if (tags.value == '0') {
          res = await addApi(addModel)
        } else {
          res = await editApi(addModel)
        }
        if (res && res.code == 200) {
          ElMessage.success(res.msg)
          await getList()
          onClose()
          eventBus.emit('menu-updated')
        }
      }
    })
  }
  const tableList = ref([])
  const getList = async () => {
    let res = await getListApi()
    if (res && res.code == 200) {
      tableList.value = res.data
    }
  }

  //表格高度
  const tableHeight = ref(0)
  onMounted(() => {
    nextTick(() => {
      tableHeight.value = window.innerHeight - 260
    })
    getList()
  })
</script>

<style scoped>
  .icon-selector {
    max-height: 300px;
    overflow: hidden;
  }

  .icon-search {
    margin-bottom: 10px;
  }

  .icon-list {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 8px;
    max-height: 250px;
    overflow-y: auto;
  }

  .icon-item {
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: 8px;
    border: 1px solid #e4e7ed;
    border-radius: 6px;
    cursor: pointer;
    transition: all 0.3s ease;
  }

  .icon-item:hover {
    border-color: #409eff;
    background-color: #f5f7fa;
  }

  .icon-active {
    border-color: #409eff;
    background-color: #ecf5ff;
  }

  .icon-item .el-icon {
    font-size: 20px;
    margin-bottom: 4px;
    color: #606266;
  }

  .icon-name {
    font-size: 12px;
    color: #909399;
    text-align: center;
    word-break: break-all;
  }

  /* 滚动条样式 */
  .icon-list::-webkit-scrollbar {
    width: 6px;
  }

  .icon-list::-webkit-scrollbar-track {
    background: #f1f1f1;
    border-radius: 3px;
  }

  .icon-list::-webkit-scrollbar-thumb {
    background: #c1c1c1;
    border-radius: 3px;
  }

  .icon-list::-webkit-scrollbar-thumb:hover {
    background: #a8a8a8;
  }
</style>